package com.citic.netty.server.bootstrap;

import com.citic.netty.common.codec.LengthFieldBasedFrameDecoderUnpacker;
import com.citic.netty.common.codec.PacketCodecHandler;
import com.citic.netty.common.handler.IMIdleStateHandler;
import com.citic.netty.server.handler.HeartBeatRequestHandler;
import com.citic.netty.server.handler.IMHandler;
import com.citic.netty.server.handler.LoginRequestHandler;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;

public class BootStrapServer {
	
	private static final int PORT = 8000;
	
	/**
	 * ChannelHandler的生命周期详解
	 * 
	 * 
	 * 
	 * 
	 * 
	 * 
	 * @param args
	 */
	public static void main(String[] args) {
		NioEventLoopGroup boosGroup = new NioEventLoopGroup();
        NioEventLoopGroup workerGroup = new NioEventLoopGroup();
        
        final ServerBootstrap serverBootstrap = new ServerBootstrap();
        serverBootstrap
        	.group(boosGroup, workerGroup)
        	.channel(NioServerSocketChannel.class)
        	.option(ChannelOption.SO_BACKLOG, 1024)
            .childOption(ChannelOption.SO_KEEPALIVE, true)
            .childOption(ChannelOption.TCP_NODELAY, true)
            .childHandler(new ChannelInitializer<NioSocketChannel>() {
				@Override
				protected void initChannel(NioSocketChannel ch) throws Exception {
					ch.pipeline().addLast(new IMIdleStateHandler());
					ch.pipeline().addLast(new LengthFieldBasedFrameDecoderUnpacker());
					ch.pipeline().addLast(PacketCodecHandler.INSTANCE);
                    ch.pipeline().addLast(LoginRequestHandler.INSTANCE);
                    ch.pipeline().addLast(HeartBeatRequestHandler.INSTANCE);
                    ch.pipeline().addLast(IMHandler.INSTANCE);
				}
            });
        
        bind(serverBootstrap, PORT);
	}

	private static void bind(ServerBootstrap serverBootstrap, int port) {
		serverBootstrap.bind(port).addListener(future -> {
            if (!future.isSuccess()) {
            	System.err.println("端口[" + port + "]绑定失败!");
            }
        });
	}
}
